import { isNavigationFailure, NavigationGuardNext, Router } from 'vue-router'
import { storage } from '@/utils/Storage'
import { start, close } from '@/utils/Nprogress'
import { ViewEnum } from '@/enums/viewEnum'
import { ACCESS_TOKEN } from '@/constants/mutation-types'
import { useAsyncRouteStoreWidthOut } from '@/stores/modules/router'
import { ErrorPageRoute } from './static-routes'
// 路由白名单
const whitePathList = [ViewEnum.LOGIN]
// 创建路由守卫
export function createRouterGuards(router: Router) {
  // 获取路由数据
  const asyncRouteStore = useAsyncRouteStoreWidthOut()
  // 路由加载前
  router.beforeEach(async (to, from, next) => {
    start()
    // 登录页面
    if (whitePathList.includes(to.path as ViewEnum)) {
      next()
      return
    }
    const token = storage.getCookie(ACCESS_TOKEN)
    if (token && to.path === '/login') {
      // 如果已登录则回到主页
      next('/home')
      return
    }
    if (!token) {
      // 如果不需要权限放行
      if (to.meta.ignoreAuth) {
        next()
        return
      }
      // 跳转至登录页面
      next(
        `/login?redirect=${to.path}&params=${JSON.stringify(to.query ? to.query : to.params)}`
      )
      storage.clearCookie()
      return
    }
    if (asyncRouteStore.getIsDynamicAddedRoute) {
      next()
      // next({ path: to.path, query: to.query })
      return
    }
    // 动态用户路由
    const routes = await asyncRouteStore.generateRoutes()
    // console.log(routes)
    if (routes == null || routes == undefined) {
      console.log('跳转至错误页面')
      nextError(router, from, to, next)
      return
    }
    asyncRouteStore.setDynamicAddedRoute(true)
    next({ path: to.path, query: to.query })
    // next()
  })

  // 路由加载后
  router.afterEach((to, _, failure) => {
    close()
    if (isNavigationFailure(failure)) {
      console.log('路由导航出错啦...')
      return
    }
    addRouteCache(to)
  })
  // 路由错误
  router.onError(error => {
    close()
    console.log(error, '路由错误')
  })
}
// 添加路由缓存
function addRouteCache(to: any) {
  const asyncRouteStore = useAsyncRouteStoreWidthOut()
  // 在这里设置需要缓存的组件名称
  const keepAliveComponents = asyncRouteStore.keepAliveComponents
  // 修改成页面缓存的路径 不要存名称，名称有可能重复
  let obj = to.matched.find((item: { path: any }) => item.path == to.path)
  if (obj == null || obj == undefined) return
  const currentComPath: any = obj.path
  if (
    currentComPath &&
    !keepAliveComponents.includes(currentComPath) &&
    to.meta.keepAlive
  ) {
    // 需要缓存的组件
    keepAliveComponents.push(currentComPath)
  } else if (!to.meta.keepAlive || to.name == 'Redirect') {
    // 不需要缓存的组件
    const index = asyncRouteStore.keepAliveComponents.findIndex(
      path => path == currentComPath
    )
    if (index != -1) {
      keepAliveComponents.splice(index, 1)
    }
  }
  asyncRouteStore.setKeepAliveComponents(keepAliveComponents)
}
// 去至错误页面
function nextError(
  router: Router,
  from: any,
  to: any,
  next: NavigationGuardNext
) {
  //添加404
  const isErrorPage = router
    .getRoutes()
    .findIndex(item => item.name === ErrorPageRoute.name)
  if (isErrorPage == -1) {
    router.addRoute(ErrorPageRoute)
  }
  const redirectPath = (from.query.redirect || to.path) as string
  const redirect = decodeURIComponent(redirectPath)
  const nextData =
    to.path === redirect ? { ...to, replace: true } : { path: redirect }
  next(nextData)
}
